package com.example.weixingateway.filter;

import com.example.weixingateway.config.properties.IgnoreWhiteProperties;
import com.weixin.common.core.constant.CacheConstants;
import com.weixin.common.core.constant.TokenConstant;
import com.weixin.common.core.utils.StringUtil;
import com.weixin.common.redis.service.RedisService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import javax.annotation.Resource;

/**
 * @version 1.0.0
 * @className: AuthFilter
 * @description: 校验所有请求的请求参数中是否包含“token”，如何不包含请求参数“token”则不转发路由
 * 1.定义过滤器AuthFilter
 * 2.获取请求对象 从请求头或参数或cookie中获取token(支持多种方式传token对于客户端更加友好，
 * 比如部分web下载请求会新建一个页面，在请求头中传token处理起来比较麻烦)
 * 3.没有token,返回401
 * 4.有token，查询redis是否有效
 * 5.无效则返回401，有效则完成验证放行
 * 6.重置token过期时间、添加内部请求头信息方便业务系统权限处理
 * @author: zhangjunfa
 * @date: 2023/2/19 10:38
 */
@Slf4j
@Component
public class AuthFilter implements GlobalFilter, Ordered {
    /**
     * 排除过滤的uri地址，nocos自行过滤
     */
    @Autowired
    private IgnoreWhiteProperties ignoreWhiteProperties;

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        String token = getToken(exchange.getRequest());
        log.info("开始网关鉴权,Token:{}", token);
        if (token == null || token.isEmpty()) {
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            log.info("开始网关鉴权,没有权限", HttpStatus.UNAUTHORIZED);
            return exchange.getResponse().setComplete();
        }
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return 0;
    }

    /**
     * 获取请求头部的Token
     *
     * @param request 请求头
     * @return
     */
    private String getToken(ServerHttpRequest request) {
        String token = request.getHeaders().getFirst(TokenConstant.AUTHENTICATION);
        // 如果前端设置了令牌前缀，则裁剪前缀
        if (StringUtils.hasText(token) && token.startsWith(TokenConstant.PREFIX)) {
            token = token.replaceFirst(TokenConstant.PREFIX, "");
        }
        return token;
    }


    /**
     * 获取缓存key
     */
    private String getTokenKey(String token) {
        return CacheConstants.LOGIN_TOKEN_KEY + token;
    }


    private void removeHeader(ServerHttpRequest.Builder mutate, String name) {
        mutate.headers(httpHeaders -> httpHeaders.remove(name)).build();
    }
}
